
package coop.bancocredicoop.proyectos.gd.alfresco

import java.io.IOException
import java.util.regex.Matcher
import java.util.regex.Pattern
import java.net.URI
import java.net.URL

import org.apache.commons.logging.LogFactory

import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpPost
import org.apache.http.client.utils.URIBuilder
import org.apache.http.client.utils.URIUtils
import org.apache.http.util.EntityUtils
import org.apache.http.NameValuePair
import org.apache.http.message.BasicNameValuePair
import org.apache.http.client.entity.UrlEncodedFormEntity
import org.apache.http.impl.cookie.BasicClientCookie

class CASClient {
    
    static final log = LogFactory.getLog(this)
    def alfrescoConfig
    URI serverURL
    URL loginURL
    URL logoutURL
    String username
    String password
    String service    

    CASClient(alfrescoConfig) {
        this.alfrescoConfig = alfrescoConfig
        serverURL = new URIBuilder(alfrescoConfig.cas.server + "/").build()
        loginURL = new URL(serverURL.toURL(), 'login')
        logoutURL = new URL(serverURL.toURL(), 'logout')
        username = alfrescoConfig.credentials.user
        password = alfrescoConfig.credentials.password
        service = alfrescoConfig.baseURL + "/"
    }    

    def getSessionIdCookie(cookieStore) {
        
        for (cookie in cookieStore.getCookies()) {
            if (cookie.getName() == "JSESSIONID") {
                return cookie.getValue()
            }
        }
        
    }

    def login(httpClient, cookieStore) {
        def loginParameters = getLoginParameters(httpClient)
        
        getServiceTicket(httpClient, loginParameters, service)
        
        def serviceURL = new URIBuilder(alfrescoConfig.baseURL)
        def sessionCookieValue = getSessionIdCookie(cookieStore)
        def sessionCookie = new BasicClientCookie("JSESSIONID", 
                                                  sessionCookieValue)
        sessionCookie.setVersion(0)
        sessionCookie.setDomain(serviceURL.getHost())
        sessionCookie.setPath(serviceURL.getPath())
        sessionCookie
    }

    private def getLoginParameters(httpClient) {
        
        def loginFormUrl = new URIBuilder(loginURL.toURI())
        loginFormUrl.setParameter("service", service)       
        def httpGet = new HttpGet(loginFormUrl.build())
        def response = httpClient.execute(httpGet)
        def body = EntityUtils.toString(response.getEntity())
        def parameters = [:]     
        parameters["lt"] = extractLt(body)
        parameters["execution"] = extractExecution(body)
        parameters["service"] = service
        parameters["username"] = username
        parameters["password"] = password
        parameters["_eventId"] = "submit"
        parameters
    }
    
  
    private String getServiceTicket(client, loginParams, String service)
    {
    
        def url = new URIBuilder(loginURL.toURI())
        url.setParameter("service", service)
        HttpPost post = new HttpPost(url.build())
        def postParameters = new ArrayList<NameValuePair>()

        loginParams.each { paramName, paramValue -> 
         postParameters.add(new BasicNameValuePair(paramName, paramValue))
        }

        post.setEntity(new UrlEncodedFormEntity(postParameters))
        
        def response = client.execute(post)
        def statusCode = response.getStatusLine().getStatusCode()
     
        if (statusCode == 302) {
            def location = response.getFirstHeader("Location")
            def matcher = location =~ /ticket=(.*)/
            def httpGet = new HttpGet(location.getValue())
            def response2 = client.execute(httpGet)
            return matcher[0][1]
        }

    }
  
    private def extractLt(body) {
        def ltMatcher = body =~ /\"lt\" value=\"(.*)\"/ 
        return ltMatcher[0][1]
    }

    private def extractExecution(body) {
        def exeMatcher = body =~ /\"execution\" value=\"(.*)\"/ 
        return exeMatcher[0][1]
    }

}

